#ifndef __MEMDB_H__
#define __MEMDB_H__

#include "utility.h"
#include "system_data.h"
#include "Parse.h"
#include "IO.h"
#include <conio.h>

typedef enum 
{
	INIT_SUCCESS,
	INIT_FAILURE,
	INIT_CONFIG_FILE_NOT_EXIST,

}init_error_code;


typedef enum 
{
	CLOSE_SUCCESS,
	CLOSE_FAILURE,

}close_error_code;

typedef enum 
{
	LOGIN_SUCCESS,
	LOGIN_FAILURE,
	LOGIN_USER_NOT_EXIST,
	LOGIN_INCORRECT_PASSWORD,
	LOGIN_TOO_MANY_WORDS,
}login_error_code;


//************************************************************************/
//* Summary:	the return value used to show the logic check of commands
//* Author:	BBzjdrk
//* Date:	2010-4-30
//* Revise:	//
//************************************************************************/
typedef enum 
{
	LOGIC_SUCCESS,
	// a general logic error
	LOGIC_ERROR,
	// database does not exist
	LOGIC_DB_NOT_EXIST,
	//  table does not exist
	LOGIC_TABLE_NOT_EXIST,
	// column does not exist
	LOGIC_COLUMN_NOT_EXIST,
	// type mismatch
	LOGIC_TYPE_UNMATCHED,

	LOGIC_DUPLICATE_DATABASE,
	LOGIC_ADD_DB_ERROR,
	LOGIC_LOG_FILE_CREATE_ERROR,
	LOGIC_DB_FILE_CREATE_ERROR,
	// 2010 - 5 - 24
	LOGIC_GET_DB_ERROR,
	LOGIC_DUPLICATE_TABLE,
	LOGIC_PRIMARY_KEY_CAN_NOT_BE_NULL,
	LOGIC_INSERT_FAILED,
	LOGIC_RUN_SCRIPT_SUCCEED,
	LOGIC_RUN_SCRIPT_FAILED,
	LOGIC_INVALID_NUMBER,
	LOGIC_INVALID_UPDATE_COMMAND,
	LOGIC_DATA_TYPE_UNMATCHED,
	// Just WARNINGS
	LOGIC_NO_PRIMARY_KEY,

	LOGIC_CREATE_TABLE_FAILURE,
	LOGIC_UNEXPECTED_ERROR,
	LOGIC_INVALID_INSERT_COMMAND,
	LOGIC_UNEXPECTED_COLUMN_NAME,
	LOGIC_VALUE_COLUMN_COUNT_UNMATCHED,
	LOGIC_VALUE_COLUMN_UNMATCHED,

	LOGIC_FLOAT_TO_INT,

	LOGIC_NOT_ALLOWED_TO_BE_NULL,
	LOGIC_NO_COLUMN_NAME_SPECIFIED,

	LOGIC_TOO_MANY_COLUMNS,
	LOGIC_DUPLICATE_KEYS


}logic_chck_value;


#define S_LOGIC_SUCCESS "general logic success"
// a general logic error
#define S_LOGIC_ERROR "general logic error"
// database does not exist
#define S_LOGIC_DB_NOT_EXIST "there is no such database."
//  table does not exist
#define S_LOGIC_TABLE_NOT_EXIST "there is no such table."
// column does not exist
#define S_LOGIC_COLUMN_NOT_EXIST "there is no such colmn"
// type mismatch
#define S_LOGIC_TYPE_UNMATCHED "the data type is unmatched."

#define S_LOGIC_DUPLICATE_DATABASE "there are two same databases."
#define S_LOGIC_ADD_DB_ERROR "error occurred when adding database."
#define S_LOGIC_LOG_FILE_CREATE_ERROR "error occurred when creating log file."
#define S_LOGIC_DB_FILE_CREATE_ERROR "error occurred when creating database file."
// 2010 - 5 - 24
#define S_LOGIC_GET_DB_ERROR "error occurred when getting database."
#define S_LOGIC_DUPLICATE_TABLE "there are two same tables."
#define S_LOGIC_PRIMARY_KEY_CAN_NOT_BE_NULL "the primery key cannot be null."
#define S_LOGIC_INSERT_FAILED "insert failed."
#define S_LOGIC_RUN_SCRIPT_SUCCEED "run script succeed."
#define S_LOGIC_RUN_SCRIPT_FAILED "run script failed."
#define S_LOGIC_INVALID_NUMBER "invalid number"
#define S_LOGIC_INVALID_UPDATE_COMMAND "update command is invalid."
#define S_LOGIC_DATA_TYPE_UNMATCHED "the data type is unmatched."
// Just WARNINGS
#define S_LOGIC_NO_PRIMARY_KEY "miss the primery key."

#define S_LOGIC_CREATE_TABLE_FAILURE "error occured when creating table"
#define S_LOGIC_UNEXPECTED_ERROR "unexcepted error."
#define S_LOGIC_INVALID_INSERT_COMMAND "insert command is invalid."
#define S_LOGIC_UNEXPECTED_COLUMN_NAME "the column name is invalid."
#define S_LOGIC_VALUE_COLUMN_COUNT_UNMATCHED "the column count is unmatched."
#define S_LOGIC_VALUE_COLUMN_UNMATCHED "the column value is unmatched."

#define S_LOGIC_FLOAT_TO_INT "data missing when convert float to int."

#define S_LOGIC_NOT_ALLOWED_TO_BE_NULL "this column data is not allowed to be null."
#define S_LOGIC_NO_COLUMN_NAME_SPECIFIED "there is no column name specified."
#define S_LOGIC_TOO_MANY_COLUMNS "there are too many columns."
#define S_LOGIC_DUPLICATE_KEYS "duplicate keys."


////************************************************************************/
////* Summary:	A struct using to create a database
////* Author:	BBzjdrk
////* Date:	2010-4-30
////* Revise:	//
////************************************************************************/
//typedef struct create_db_struct
//{
//	// The name of the new db
//	char* p_db_name;
//	// The table's create time
//	time_t create_time;
//	// The size of the database
//	int i_size;
//	// The table list
//	DECLARE_LISTP(table) p_tables;
//
//}create_db_struct;

/************************************************************************/
/* Summary:	A struct using to startup a database
/* Author:	BBzjdrk
/* Date:	2010-4-30
/* Revise:	//
/************************************************************************/
typedef struct
{
	// The startup time
	time_t	start_time;
	// The filepath the database file stored
	char	file_path[MAX_PATH_LENGTH_P1];
	// The password to open the database
	char	password[MAX_USER_PWD_LENGTH];
	// The user_name of the database
	char	user_name[MAX_USER_PWD_LENGTH];

}db_startup_struct;

//************************************************************************/
//* Summary:	The return value of a startup function, the actual meaning is 
//described by these words.
/* Author:	BBzjdrk
/* Date:	2010-4-30
/* Revise:	//
/* Attention:
//	
//	///////////////////////////////////////////////////////////////////////////////
//	The connection string format is like this:
//		
//		server=_ip:_port;User = _username; Password = _userpwd; Database = _dbname
//
//	Example: 
//	
//		connect to server=192.168.1.111:6666, user = shiwen, password = shiwen,database = sbdb
//
///////////////////////////////////////////////////////////////////////////////
//************************************************************************/
typedef enum 
{
	// Succeed
	CONNECT_SUCCEED,
	// Incorrent password
	CONNECT_INCORRECT_PWD,
	// The username specified does not exist
	CONENCT_NONEXIST_USER,
	// The connection time been exceeded
	CONNECT_TIME_OUT,
	// The database does not exist
	CONNECT_DB_NOTEXIST

}connection_return_value;

//************************************************************************/
//* Summary:	The return value of a startup function, the actual meaning is 
//			described by those enum types.
//* Author:	BBzjdrk
//* Date:	2010-4-30
//* Revise:	//
//************************************************************************/
typedef enum 
{
	// succeed
	STARTUP_SUCCEED,
	// incorrect password
	STARTUP_INCORRECT_PWD,
	// the db does not exist
	STARTUP_DB_NOTEXIST

}startup_return_value;

//************************************************************************/
//* Summary:	Delete table using the table name specified
//* Return:	Succeed if succeed, 0 otherwise
//* Param0:	The core application struct
//* Author:	BBzjdrk
//* Date:		
//* Revise:	//
//************************************************************************/
void dispatch_command(MMDB* p_memdb);

//************************************************************************/
//* Summary:	Listen to a connection to be established. 
//* Return:	Succeed if succeed, other values otherwise
//* Param0:	The startup struct used to start a database
//* Author:	
//* Date:		
//* Revise:	//
//************************************************************************/
connection_return_value get_connection( char* p_connection_str , database** pp_cur_db);

//************************************************************************/
//* Summary:	To start a database using the start_struct
//* Return:	Succeed if succeed, other values otherwise
//* Param0:	The startup struct used to start a database
//* Author:	
//* Date:		
//* Revise:	//
//************************************************************************/
startup_return_value startup_db(db_startup_struct* p_startup_struct);


//************************************************************************/
//* Summary:	Validate the logic
//* Return:	TRUE if pass, FALSE otherwise,  only display error messages
//* Param0:	The property of the table
//* Param1:	The input raw_values
//* Author:	
//* Date:		
//* Revise://
//************************************************************************/
logic_chck_value logic_validate(struct database *p_database, struct table* p_table, raw_value* p_raw_value );

/************************************************************************/
/* Summary:	Find the db index using the db_name
/* Return:	the index if exists, -1 if not.
/* Param0:	The	MMDB struct
/* Param1:	The name of the database
/* Author:	
/* Date:		
/* Revise:	//
************************************************************************/
int find_db_index(struct MMDB* p_mmdb, char* p_db_name);



/************************************************************************/
/* Summary: to process the create database command
/* Return:	
/* Param0: the  command 
/* Author:	BBzjdrk
/* Date:		2010-5-21
/* Revise:	//
************************************************************************/
logic_chck_value process_create_db(MMDB* p_memdb, cmd_t cmd, database** pp_cur_db );



/************************************************************************/
/* Summary: to show error messages when the command has any 
grammar error
/* Return:		N/A
/* Param0: the return value of command string processing
/* Author:	BBzjdrk
/* Date:		2010-5-17
/* Revise:	//
************************************************************************/
void show_error_message(grammar_chck_value ret);

/************************************************************************/
/* Summary: to show error messages when the command has any 
grammar error
/* Return:		N/A
/* Param0: the return value of command string processing
/* Author:	BBzjdrk
/* Date:		2010-5-17
/* Revise:	//
************************************************************************/
void show_logic_error_message(grammar_chck_value ret);

/************************************************************************/
/* Summary: the entry of the whole program 
/* Return:		N/A
/* Author:	BBzjdrk
/* Date:		2010-5-17
/* Revise:	//
************************************************************************/
logic_chck_value start_memdb();

/************************************************************************/
/* Summary: initialize a command struct
/* Return:		N/A
/* Param0:	a pointer directing to the command struct
/* Author:	BBzjdrk
/* Date:		2010-5-17
/* Revise:	//
************************************************************************/
void initialize_cmd(cmd_t *p_cmd);

/************************************************************************/
/* Summary: To create a database using the given information
/* Return:		a logic chck value representing the result
/* Param0:	a struct from the cmd_t
/* Author:	BBzjdrk
/* Date:		2010-5-23
/* Revise:	//
************************************************************************/
logic_chck_value create_database(MMDB* p_memdb, create_db_struct_t db_create_struct, database** pp_cur_db);

/************************************************************************/
/* Summary: To validate the create command
/* Return:		a logic chck value representing the result
/* Param0:	the core application whitch has the list of database
/* Param1:	a struct from the cmd_t
/* Author:	BBzjdrk
/* Date:		2010-5-23
/* Revise:	//
************************************************************************/
logic_chck_value validate_create_database(MMDB* p_memdb, create_db_struct_t db_create_struct);




/************************************************************************/
/* Summary: To initialize the memory db application
/* Return:		The core struct of this application
/* 
/* Author:		BBzjdrk
/* Date:			2010-5-23
/* Revise:	//
************************************************************************/
MMDB*  app_factory_create();

/************************************************************************/
/* Summary: To close the application, release the resources allocated
/* Return:		the close information
/* Param0:	The application struct
/* Author:		BBzjdrk
/* Date:			2010-5-23
/* Revise:	//
************************************************************************/
close_error_code close_app(MMDB* p_memdb);

/************************************************************************/
/* Summary: To load configuration from configuration file
/* Return:		The core struct of this application
/* Param0:	The application struct
/* Author:		BBzjdrk
/* Date:			2010-5-23
/* Revise:	//
************************************************************************/
init_error_code load_config(MMDB* p_memdb);

/************************************************************************/
/* Summary: The login function
/* Return:		The login result
/* Param0:	The application struct
/* Author:		BBzjdrk
/* Date:			2010-5-23
/* Revise:	//
************************************************************************/
login_error_code login(MMDB* p_memdb);

/************************************************************************/
/* Summary: To check if the db name exists
/* Return:		TRUE if exists, FALSE otherwise
/* Param0:	The core application struct
/* Param1:	The name of the database
/* Author:		BBzjdrk
/* Date:			2010-5-23
/* Revise:	//
************************************************************************/
BOOL_EX is_db_exist(MMDB *p_memdb, char* p_db_name);




void free_system_resource(MMDB* p_dbms);

/************************************************************************/
/* Summary: Run a script file which containing the sql commands.
/* Return:		success if the file has finished successfully
/* Param0:	the script file name
/* Parma1:	the current application instance
/* Param2:	the current working database
/* Author:		BBzjdrk
/* Date:			2010-5-30
/* Revise:	//
************************************************************************/
logic_chck_value run_script( char* p_file_name, MMDB* p_memdb, database **pp_cur_db);


void show_data_set(DataSet *p_ds);

void show_data(data_type_t tp, data_t data);

#endif /*__MEMDB_H__*/
